#pragma once

// base classes
#include "API/TESForms/TESForm.h" // TESFormIDListView
#include "API/TESForms/BaseFormComponent.h" // additonal form components
#include "Components/ExtendedForm.h"

#include "API/Magic/Magic.h"

#include "NiTOrphanList.h"

// Macros for short name and class name, which must be unique among all plugins, and just this plugin, respectively
#define MAGICITEMGENERATOR_SHORTNAME "ARMI"
#define MAGICITEMGENERATOR_CLASSNAME "MagicItemGenerator"

class EffectItem;
#include "Submodule/EffectItemGenerator.h"

class TESObjectARMO;
class TESObjectCLOT;
class TESObjectWEAP;

class MagicItemGenerator : public TESForm {
public:

    // members
    // TESForm	//	018/024
	MEMBER bool			suf;

	MEMBER UInt16		minUses;
	MEMBER UInt16		maxUses;
	MEMBER SInt16		rank;
	MEMBER UInt8		freq;
	MEMBER bool			autocalc;
	
    MEMBER BSStringT	sub;
	MEMBER BSStringT	pet;
	MEMBER BSStringT	les;
	MEMBER BSStringT	com;
	MEMBER BSStringT	grt;
	MEMBER BSStringT	gnd;
	MEMBER BSStringT	ult;
	MEMBER BSStringT	neg;
	MEMBER UInt8		souls;
	
	MEMBER NiTOrphanList<EffectItemGenerator> eigs;
	MEMBER NiTOrphanList<EffectItemGenerator> negs;

	// TESFormIDListView virtual method overrides
	// Note the use of the '_LOCAL' macro to indicate that these functions are being (re)implemented by this plugin
	_LOCAL virtual				~MagicItemGenerator();
	_LOCAL virtual bool			LoadForm(TESFile& file);
	_LOCAL virtual void			SaveFormChunks();
	_LOCAL virtual UInt8		GetFormType();
	_LOCAL virtual void			CopyFrom(TESForm& form);
	_LOCAL virtual bool			CompareTo(TESForm& compareTo);
#ifndef OBLIVION
	_LOCAL virtual void			SetInDialog(HWND dialog);
	_LOCAL virtual void			GetFromDialog(HWND dialog);
#endif

	// constructor
	_LOCAL MagicItemGenerator();
	_LOCAL MagicItemGenerator(const MagicItemGenerator& copied);
    
	// COEF ExtendedForm component
	static ExtendedForm         extendedForm;
	_LOCAL static TESForm*      CreateMagicItemGenerator(); // creates a blank UseList

	MEMBER bool					GetIsSuffix() const;
	MEMBER bool					SetIsSuffix(bool new_suf);
	MEMBER UInt16				GetMinUses() const;
	MEMBER bool					SetMinUses(UInt16 new_min);
	MEMBER UInt16				GetMaxUses() const;
	MEMBER bool					SetMaxUses(UInt16 new_max);
	MEMBER SInt16				GetRank() const;
	MEMBER bool					SetRank(SInt16 new_rank);
	MEMBER UInt8				GetFrequency() const;
	MEMBER bool					SetFrequency(UInt8 new_freq);
	MEMBER bool					GetIsAutocalc() const;
	MEMBER bool					SetIsAutocalc(bool new_auto);

	MEMBER UInt8				GetAffixMask() const;

	MEMBER BSStringT			GetAffix(UInt8 soul) const;
	MEMBER bool					SetAffix(const BSStringT& new_aff, UInt8 soul);
	MEMBER BSStringT			GetAffixSubpetty() const;
	MEMBER bool					SetAffixSubpetty(const BSStringT& new_sub);
	MEMBER BSStringT			GetAffixPetty() const;
	MEMBER bool					SetAffixPetty(const BSStringT& new_pet);
	MEMBER BSStringT			GetAffixLesser() const;
	MEMBER bool					SetAffixLesser(const BSStringT& new_les);
	MEMBER BSStringT			GetAffixCommon() const;
	MEMBER bool					SetAffixCommon(const BSStringT& new_com);
	MEMBER BSStringT			GetAffixGreater() const;
	MEMBER bool					SetAffixGreater(const BSStringT& new_grt);
	MEMBER BSStringT			GetAffixGrand() const;
	MEMBER bool					SetAffixGrand(const BSStringT& new_gnd);
	MEMBER BSStringT			GetAffixUltragrand() const;
	MEMBER bool					SetAffixUltragrand(const BSStringT& new_ult);
	MEMBER BSStringT			GetAffixNegative() const;
	MEMBER bool					SetAffixNegative(const BSStringT& new_neg);

	MEMBER bool					HasPositiveEffects() const;
	MEMBER bool					HasNegativeEffects() const;
	MEMBER bool					HasApparelEffects() const;
	MEMBER bool					HasWeaponEffects() const;

#ifdef OBLIVION
	// Game execution code: dynamic item generation

	MEMBER UInt16				Generate(std::vector<EffectItem*>& geis, UInt8 soul, Magic::RangeTypes range, UInt8 chrgB = 0) const;

#else // #ifndef OBLIVION
	// CS dialog management

	static bool					mod;
	static MagicItemGenerator*	currPtr;
	static UInt32               kMenuIdentifier;   // identifier for new menu item
	static HWND                 dialogHandle; // handle of dialog if currently open
	_LOCAL static void          OpenDialog(); // opens dialog if it is not currently open
	_LOCAL static INT_PTR CALLBACK	DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); // processes menu messages
	_LOCAL int					DialogFind(); // finds this in the listview
	_LOCAL static bool			DialogSave(); // saves the current MIG
	_LOCAL static bool			ConfirmCurrChanges(); // asks if the user wants to save a MIG before closing it.
	_LOCAL static bool			DialogSelect(); // cleans up one MagicItemGenerator and calls SetInDialog for another
	_LOCAL static bool			DialogNew(); // cleans up one MagicItemGenerator and calls SetInDialog for a fresh one
	_LOCAL static void			DialogModified(bool mod); // sets various settings after the dialog has been modified, or unsets when saved
	_LOCAL static bool			DialogDelete(); // deletes an MIG from the list.
	_LOCAL static void			DialogEditEig(UINT dlgItem, LRESULT& sel); // edits or creates a new EffectItemGenerator
	_LOCAL static void			DialogDeleteEig(UINT dlgItem); // removes an EffectItemGenerator
	_LOCAL static void			DialogCleanup(HWND dialog); // cleans up after dialog is closed
	_LOCAL static void			DialogImport(); // imports MIGs from a tab-delimited text file

#endif

	// global initialization function, called once when submodule is first loaded
	_LOCAL static void          InitializeMagicItemGenerator();

private:
};